using System;
using System.Diagnostics.Contracts;

namespace OpenWaves
{
    public partial class AbsoluteUrl : Url
    {
        public AbsoluteUrl(Uri uri) : base(uri)
        {
            Contract.Requires<ArgumentNullException>(uri != null);
            Contract.Requires<ArgumentException>(uri.IsAbsoluteUri);

            this.path = UrlPath.Parse(uri.AbsolutePath);
            this.query = UrlQueryCollection.Parse(uri.Query);
            this.fragment = String.IsNullOrEmpty(uri.Fragment) ? String.Empty : uri.Fragment.Substring(1);
        }

#if !SILVERLIGHT        
        [NonSerialized]
#endif
        private readonly UrlPath path;
#if !SILVERLIGHT
        [NonSerialized]
#endif
        private readonly UrlQueryCollection query;
#if !SILVERLIGHT
        [NonSerialized]
#endif
        private AbsoluteUrl hostUrl;

        public override UrlPath Path
        {
            get { return this.path; }
        }

        public override UrlQueryCollection Query
        {
            get { return this.query; }
        }

#if !SILVERLIGHT
        [NonSerialized]
#endif
        private readonly string fragment;
        public override string Fragment
        {
            get { return this.fragment; }
        }

        public string Scheme
        {
            get { return this.Uri.Scheme; }
        }

        public string Host
        {
            get { return this.Uri.Host; }
        }

        public int Port
        {
            get { return this.Uri.Port; }
        }

        public string UserInfo
        {
            get { return this.Uri.UserInfo; }
        }

        public override AbsoluteUrl ResolveAgainst(AbsoluteUrl baseUrl)
        {
            return this;
        }

        protected override UrlBuilder CreateBuilder()
        {
            return AbsoluteUrlBuilder.From(this);
        }

        protected override string ToUrlString()
        {
            return UnifySpaceEncoding(this.Uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped));
        }

        public override string ToUnescapedString()
        {
            return this.Uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.Unescaped);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        public new AbsoluteUrlBuilder GetBuilder()
        {
            return AbsoluteUrlBuilder.From(this);
        }

        public AbsoluteUrl HostUrl
        {
            get
            {
                if(this.hostUrl==null)
                {
                    var urlBuilder = new AbsoluteUrlBuilder
                                                        {
                                                            Scheme = Scheme,
                                                            Port = Port,
                                                            Host = Host
                                                        };
                    this.hostUrl = urlBuilder.ToUrl();
                }

                return this.hostUrl;
            }
        }
    }
}
